package com.maybach.web.controller.certificate;

import com.audi.dubbo.api.admin.models.AdminModel;
import com.maybach.common.po.EnterpriseCertificatePO;
import com.maybach.component.city.CityData;
import com.maybach.component.city.domain.City;
import com.maybach.component.city.domain.Province;
import com.maybach.core.ao.CertificateAO;
import com.maybach.core.ao.FlowApplyAO;
import com.maybach.core.ao.UserAO;
import com.maybach.core.dubbo.consumer.adapter.AdminServiceDubooAdapter;
import com.maybach.core.form.flow.TaskActForm;
import com.maybach.core.form.partner.PartnerForm;
import com.maybach.core.form.partner.PartnerQueryForm;
import com.maybach.util.StringUtil;
import com.maybach.util.query.support.PageResult;
import com.maybach.web.constants.WebConstants;
import com.maybach.web.framework.util.WebUtil;
import com.maybach.workflow.common.api.enums.FlowActTypeEnum;
import com.maybach.workflow.common.api.enums.FlowStateEnum;
import com.maybach.workflow.common.model.FlowApplyDO;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by houenxun on 16/1/22.
 * 企业信息认证
 */
@Controller
@RequestMapping("/certificate/enterprise/")
public class EnterpriseCertificateController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private UserAO userAO;

    @Autowired
    private FlowApplyAO flowApplyAO;

    @Autowired
    private CertificateAO certificateAO;

    @Autowired
    private AdminServiceDubooAdapter adminServiceDubooAdapter;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }


    /**
     * 用户认证管理页面
     *
     * @return
     */
    @RequiresAuthentication
    @RequestMapping(value = "list", method = RequestMethod.GET)
    public String list(@ModelAttribute("partnerQueryForm") PartnerQueryForm partnerQueryForm, BindingResult bindingResult, ModelMap model) {
        if (null == partnerQueryForm) {
            partnerQueryForm = new PartnerQueryForm();
        }
        if (!model.containsAttribute("partnerQueryForm")) {
            model.addAttribute(partnerQueryForm);
        }
        try {
            if (null == partnerQueryForm.getStatus()) {
                partnerQueryForm.setStatus(Arrays.asList(FlowStateEnum.init.getStatus(), FlowStateEnum.reject.getStatus()));
            }
            PageResult<FlowApplyDO> result = certificateAO.queryEnterpriseCertificate(partnerQueryForm);
            model.addAttribute("pageResult", result);
            return "certificate/enterprise/list";

        } catch (Exception e) {
            logger.error("", e);
            return "result";
        }
    }

    @RequiresAuthentication
    @RequestMapping(value = "audit")
    public String audit(@RequestParam("taskId") Long taskId, @RequestParam(required = false, value = "redirectUrl") String redirectUrl, Model model) {

        model.addAttribute(WebConstants.REDIRECT_URL_KEY, redirectUrl);

        FlowApplyDO applyDO = flowApplyAO.getApplyByTaskId(taskId);
        model.addAttribute("applyDO", applyDO);
        model.addAttribute("applyContent", applyDO.getContentObject());

        EnterpriseCertificatePO certificatePO = (EnterpriseCertificatePO) applyDO.getContentObject();


        if (!model.containsAttribute("taskActForm")) {
            TaskActForm taskActForm = new TaskActForm();
            taskActForm.setTaskId(taskId);
            taskActForm.setMemo(certificatePO.getMemo());
            model.addAttribute("taskActForm", taskActForm);
        }


        if (!model.containsAttribute("partnerForm")) {

            PartnerForm partnerForm = assembly(certificatePO);

            model.addAttribute("partnerForm", partnerForm);
        }

        Map<String, String> map =  getUsersByDubbo("b2bManager");

        model.addAttribute("admin", map);

        return "certificate/enterprise/audit";
    }


    private Map<String,String> getUsersByDubbo(String role){
        List<AdminModel> list = adminServiceDubooAdapter.getAdminModelByRoleCode(role);

        Map<String, String> map = new HashMap<String, String>();
        for(AdminModel model : list){
            map.put(model.getAdminId()+"", getName(model));
        }
        return map;
    }

    private String getName(AdminModel model){
        if(StringUtil.isNotBlank(model.getExtattr())){
            return model.getExtattr();
        }
        return model.getNick();
    }

    private PartnerForm assembly(EnterpriseCertificatePO certificatePO) {
        PartnerForm partnerForm = new PartnerForm();
        partnerForm.setCertificateCode(certificatePO.getCertificateCode());
        partnerForm.setContactsPhone(certificatePO.getContactsPhone());
        partnerForm.setContactsName(certificatePO.getContactsName());
        partnerForm.setCorpName(certificatePO.getCorpName());
        partnerForm.setCorpLogoImgs(certificatePO.getCorpLogoImgs());
        partnerForm.setContractImgs(certificatePO.getContractImgs());
        partnerForm.setStoreImgs(certificatePO.getStoreImgs());
        partnerForm.setLegalCertImgs(certificatePO.getLegalImgs());
        partnerForm.setCityId(certificatePO.getCity());
        partnerForm.setProviceId(certificatePO.getProvince());
        partnerForm.setDetailAddress(certificatePO.getDetailAddress());
        partnerForm.setCredentialsImgs(certificatePO.getCredentialsImgs());
        partnerForm.setPartnerMemo(certificatePO.getPartnerMemo());
        partnerForm.setCorpDescription(certificatePO.getCorpDescription());
        partnerForm.setManager(certificatePO.getManager());

        if(null == partnerForm.getProviceId() || partnerForm.getProviceId() == 0){
            if(null != partnerForm.getCityId()){
                City city = CityData.getCityById(partnerForm.getCityId());
                if(null != city){
                    partnerForm.setProviceId(city.getProID());
                }
            }
        }
        return partnerForm;
    }

    private  EnterpriseCertificatePO assembly(EnterpriseCertificatePO certificatePO ,PartnerForm partnerForm, TaskActForm taskActForm) {
        certificatePO.setCertificateCode(partnerForm.getCertificateCode());
        certificatePO.setContactsPhone(partnerForm.getContactsPhone());
        certificatePO.setContactsName(partnerForm.getContactsName());
        certificatePO.setCorpName(partnerForm.getCorpName());
        certificatePO.setLegalImgs(partnerForm.getLegalCertImgs());
        certificatePO.setCorpLogoImgs(partnerForm.getCorpLogoImgs());
        certificatePO.setContractImgs(partnerForm.getContractImgs());
        certificatePO.setStoreImgs(partnerForm.getStoreImgs());
        certificatePO.setLegalImgs(partnerForm.getLegalCertImgs());
        certificatePO.setCity(partnerForm.getCityId());
        certificatePO.setProvince(partnerForm.getProviceId());
        certificatePO.setCredentialsImgs(partnerForm.getCredentialsImgs());
        certificatePO.setMemo(taskActForm.getMemo());
        certificatePO.setPartnerMemo(partnerForm.getPartnerMemo());
        certificatePO.setCityName(this.getCityName(partnerForm.getProviceId(), partnerForm.getCityId()));
        certificatePO.setDetailAddress(partnerForm.getDetailAddress());
        certificatePO.setCorpDescription(partnerForm.getCorpDescription());
        certificatePO.setManager(partnerForm.getManager());
        return certificatePO;
    }

    /**
     * 处理无效省份和直辖市
     * @param partnerForm
     */
    private void processProvice(PartnerForm partnerForm) {
        if(null != partnerForm.getProviceId()){
            Province province = CityData.getProvinceById(partnerForm.getCityId());
            if(null == province){
                partnerForm.setProviceId(null);
                partnerForm.setCityId(null);
            }else{
                if(province.getRemark().equals("直辖市")){
                    partnerForm.setCityId(null);
                }
            }
        }
    }

    protected String getCityName(Integer proviceId, Integer cityId) {
        if (null != proviceId) {
            Province province = CityData.getProvinceById(proviceId);
            if (null != province) {
                City city = null != cityId ? CityData.getCityById(cityId) : null;
                if (city == null) {
                    return province.getName();
                } else {
                    return province.getName() + city.getName();
                }
            }
        }
        return null;
    }


    @RequestMapping(value = "doAudit", method = RequestMethod.POST)
    @RequiresAuthentication
    public String doAudit(HttpServletRequest request, @RequestParam(required = false, value = "redirectUrl") String redirectUrl, @Valid @ModelAttribute("taskActForm") TaskActForm taskActForm, BindingResult bindingResult, @Valid @ModelAttribute("partnerForm") PartnerForm partnerForm, BindingResult parnerBindingResult, ModelMap model, RedirectAttributes redirectAttributes) throws Exception {
        if (bindingResult.hasErrors() || (StringUtils.equals(taskActForm.getActType(), FlowActTypeEnum.pass.name()) && parnerBindingResult.hasErrors())) {
            WebUtil.storeFlashAttribute(redirectAttributes, model);
            return "redirect:" + WebUtil.getLastUrlFromReferer(request);
        }
        model.addAttribute(WebConstants.REDIRECT_URL_KEY, redirectUrl);

        FlowApplyDO flowApplyDO = flowApplyAO.getApplyByTaskId(taskActForm.getTaskId());
        EnterpriseCertificatePO certificatePO = (EnterpriseCertificatePO) flowApplyDO.getContentObject();
        processProvice(partnerForm);
        certificatePO = this.assembly(certificatePO, partnerForm, taskActForm);
        flowApplyDO.setContentObject(certificatePO);
        flowApplyAO.updateApply(flowApplyDO);

        flowApplyAO.executeTask(taskActForm);
        return WebConstants.COMMON_RESULT_PAGE;
    }


}
